Flask

您所在的位置:网站首页 flask sqlalchemy查询语句 Flask

Flask

2023-07-12 04:38| 来源: 网络整理| 查看: 265

使用 Flask-SQLAlchemy 从数据库中查询数据,可以指定查询的条件。数据库中的数据很多,用户需要的只是某一条数据或满足某个条件的数据。

在 Flask-SQLAlchemy 中,指定查询条件是通过数据对象的 query 对象来实现的,query 对象中实现了很多常用的过滤方法,可以方便地实现过滤查询。

一、准备数据库和数据表

1. 创建一个 flask_alchemy_search.py 文件,编写连接数据库和模型类的代码并运行,创建两个数据表。

from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://admin:[email protected]:3306/MyDB_one' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True app.config['SQLALCHEMY_ECHO'] = True db = SQLAlchemy(app) class Phone(db.Model): __tablename__ = 'Phone_tb' pid = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(32)) person = db.relationship('Person', backref='phone', lazy='dynamic') def __repr__(self): return 'Phone_name: {}'.format(self.name) class Person(db.Model): __tablename__ = 'Person_tb' mid = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) age = db.Column(db.Integer) phone_id = db.Column(db.Integer, db.ForeignKey('Phone_tb.pid')) def __repr__(self): return 'Person_name: {}'.format(self.name) db.drop_all() db.create_all() if __name__ == '__main__': app.run(debug=True)

使用创建好的 MySQL 用户 admin 连接数据库,在 MyDB_one 数据库中先删除再创建两张数据表 Phone_tb 和 Person_tb 。

2. 创建完成数据表后,将代码中的 db.drop_all() ,db.create_all() 和 app.run(debug=True) 注释掉。

二、在数据表中批量插入数据

因为相同的代码在之前已经使用过,所以在准备数据表时,先将数据表删除了,重新建新的表。数据表是空,要查询数据,数据表中首先要有数据,先批量添加数据到数据表中。

if __name__ == '__main__': phone_one = Phone(name='IPhone') phone_two = Phone(name='Mi') phone_three = Phone(name='NOKIA') phone_four = Phone(name='HUAWEI') phone_five = Phone(name='OPPO') phone_six = Phone(name='VIVO') db.session.add_all([phone_one, phone_two, phone_three, phone_four, phone_five, phone_six]) db.session.commit() per_one = Person(name='You', age=18, phone_id=1) per_two = Person(name='Me', age=81, phone_id=3) per_three = Person(name='JackMa', age=60, phone_id=2) per_four = Person(name='Panshiyi', age=50, phone_id=4) per_five = Person(name='DingLei', age=40, phone_id=1) db.session.add_all([per_one, per_two, per_three, per_four, per_five]) db.session.commit()

在 flask_alchemy_search.py 中继续添加上面的代码,运行,会在数据表 Phone_tb 中添加 6 条数据,在数据表 Person_tb 中添加 5 条数据。

这些数据用于后面使用 Flask-SQLAlchemy 进行过滤查询的素材。

三、使用 Flask-SQLAlchemy 进行过滤查询

数据添加完成,注释掉添加数据的代码,(表中有唯一字段,重复添加会报错),然后开始查询数据。

1. 查询表中的所有对象

all_person = Person.query.all() print(all_person)

使用 query 对象的 all() 方法来查询表中的所有数据,返回的结果是所有数据组成的一个列表,显示的字段是 __repr__ 中定义的字段。

如查询 Person_tb 中的所有数据,运行结果:

[Person_name: You, Person_name: Me, Person_name: JackMa, Person_name: Panshiyi, Person_name: DingLei]

2. 查询表中的第一个对象

first = Person.query.first() print(first)

使用 query 对象的 first() 方法来查询表中的第一条数据。

Person_name: You

3. 主键查询,如果主键不存在则无返回内容

three = Person.query.get(3) print(three)

使用 query 对象的 get() 方法来根据主键查询数据,在 get() 中传入一个表中存在的主键值。

Person_name: JackMa

4. 精确查询,获取满足条件的数据

person_p = Person.query.filter_by(name='Panshiyi').all() print(person_p)

使用 query 对象的 filter_by() 方法来指定条件查询精确的数据,精确查询需要指定某个字段完整的值。

在 filter_by() 中通过键值对指定查询条件,在 filter_by() 方法后需要链式跟上 all() 方法,才能返回查询对象。

[Person_name: Panshiyi]

5. 模糊查询,返回满足条件的数据

person_i = Person.query.filter(Person.name.endswith('i')).all() print(person_i)

使用 query 对象的 filter() 方法来查询满足条件的数据,在 filter() 中通过数据对象的字段特征来指定查询条件。

[Person_name: Panshiyi, Person_name: DingLei]

6. 通过 != 进行取反查询

boss = Person.query.filter(Person.name != 'Me').all() print(boss)

在 filter() 方法中,指定对象属性的取反条件,可以完成逻辑非的查询。

[Person_name: You, Person_name: JackMa, Person_name: Panshiyi, Person_name: DingLei]

7. and_ 进行 逻辑与 查询

from sqlalchemy import and_ oppo = Phone.query.filter(and_(Phone.name.startswith('o'), Phone.name.endswith('o'))).all() print(oppo)

先从 sqlalchemy 中导入 and_ ,用于 逻辑与 查询。将并列的条件写在 and_() 中,返回结果是同时满足 and_() 中的所有条件的所有数据。

上面创建了两张数据表,现在换一张表查询,如查询开头结尾都是 o 字母的手机品牌,运行结果如下:

[Phone_name: OPPO]

8. not_ 进行 逻辑非 查询

from sqlalchemy import and_, not_ vivo = Phone.query.filter(and_(not_(Phone.name.startswith('o')), Phone.name.endswith('o'))).all() print(vivo)

上面使用 != 指定对象属性可以实现逻辑非,也可以使用 sqlalchemy 中的 not_ 实现逻辑非查询。

先从 sqlalchemy 中导入 not_ ,将取反的条件写在 not_() 中,返回的查询结果就是取反的结果。

[Phone_name: VIVO]

9. or_ 进行 逻辑或 查询

from sqlalchemy import or_ phone_i = Phone.query.filter(or_(Phone.name.startswith('i'), Phone.name.endswith('i'))).all() print(phone_i)

先从 sqlalchemy 中导入 or_ ,将查询的条件写在 or_() 中,返回的查询结果是满足其中任意一条条件的所有数据。

[Phone_name: IPhone, Phone_name: Mi, Phone_name: HUAWEI]

四、Flask-SQLAlchemy 关系字段和关联查询

在上面创建的两张表中,已经设置了关系字段。

Person 与 Phone 的关系是一对多的关系。

在 Person 模型类中,定义了关系字段 phone_id 。

phone_id = db.Column(db.Integer, db.ForeignKey('Phone_tb.pid'))

这个关系字段关联到了 Phone 模型类中的主键 pid 。

在 Phone 模型类中,定义了关系字段 person 。

person = db.relationship('Person', backref='phone', lazy='dynamic')

通过 realtionship 描述了 Phone 和 Person 的关系,这种关系有一对多,多对多等,上面的两张表是一对多的关系,Person 是 '一' ,Phone 是 '多' ,realtionship 字段定义在 '多' 的模型类中。

在 realtionship 中,第一个参数为对应 '一' 的模型类 "Person" 。

第二个参数 backref 是在模型类 Person 中申明一条新属性的方法,这个属性名是通过关系字段查询数据时使用的属性。在数据表中,不会创建这个字段(也可以说是隐藏字段),但是这个属性名不能与 Person 中已有的属性同名,否则属性冲突,在数据表中添加数据时会报错。

第三个参数 lazy 是可选的,决定了什么时候 SQLALchemy 从数据库中加载数据,是一种优化查询速度的方式,对于数据量大或查询条件比较复杂时会有用,具体可以自己扩展一下。

接下来,进行关联查询。

me = Person.query.get(2) me_phone = me.phone print(me_phone)

先从 Person 中查出一条数据,然后通过关系字段查询 Phone 中的数据,返回的是一个 Phone 对象,而不是一个字段值。

这就完成了从 Person 中的关系字段查询到 Phone 中的对象。

Phone_name: NOKIA


【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3